<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Web Worker 演示</h1>

    <div>
      <label for="number">输入数字：</label>
      <input type="number" id="number" value="40" />
      <button onclick="startWorker()">开始计算</button>
      <button onclick="stopWorker()">停止计算</button>
    </div>

    <div id="result"></div>
    <div id="error"></div>
    <script>
      /**
     * 工作原理：

      1. 独立线程：Web Worker 在一个与主线程（UI 线程）分离的线程中运行，
          主线程和 Worker 线程之间通过消息传递（postMessage）进行通信。

      2. 主线程与 Worker 通信：主线程可以通过 postMessage() 方法向 Worker 发送数据，
          Worker 完成计算后，通过 postMessage() 将结果返回给主线程。

      3. 异步操作：由于 Worker 在后台线程中运行，因此它的执行不会阻塞主线程，所有的计算任务都是异步执行的。

      4. 线程间通信：Worker 无法直接访问主线程的 DOM、window 或者 document 等对象，
          它只能通过 postMessage() 与主线程进行数据交换。返回的数据是通过事件机制传递的，使用 onmessage 监听数据的返回。
    */
      let myWorker;
      const resultDiv = document.getElementById("result");
      const errorDiv = document.getElementById("error");

      // 创建Worker
      function startWorker() {
        // 使用Blob URL创建内联Worker
        const workerCode = `
                self.onmessage = function(e) {
                    const num = parseInt(e.data);
                    if (isNaN(num) || num < 0) {
                        self.postMessage({ error: '请输入有效的正整数' });
                        return;
                    }

                    // 计算斐波那契数列（耗时操作）
                    function fibonacci(n) {
                        if (n <= 1) return n;
                        return fibonacci(n-1) + fibonacci(n-2);
                    }

                    try {
                        const result = fibonacci(num);
                        self.postMessage({ result });
                    } catch (err) {
                        self.postMessage({ error: err.message });
                    }
                };
            `;

        const blob = new Blob([workerCode], { type: "text/javascript" });
        const workerUrl = URL.createObjectURL(blob);

        myWorker = new Worker(workerUrl);

        // 接收Worker消息
        myWorker.onmessage = function (e) {
          if (e.data.error) {
            errorDiv.textContent = e.data.error;
            resultDiv.textContent = "";
          } else {
            resultDiv.textContent = `计算结果：${e.data.result}`;
            errorDiv.textContent = "";
          }
        };

        // 监听Worker错误
        myWorker.onerror = function (e) {
          errorDiv.textContent = `Worker错误：${e.message}`;
        };

        // 发送消息给Worker
        const number = document.getElementById("number").value;
        myWorker.postMessage(number);
      }

      // 终止Worker
      function stopWorker() {
        if (myWorker) {
          myWorker.terminate();
          resultDiv.textContent = "Worker已终止";
          errorDiv.textContent = "";
        }
      }
    </script>
  </body>
</html>
